package aeolus.wind.spider.biz.service.impl;

import java.util.ArrayList;
import java.util.List;

import aeolus.wind.spider.biz.constants.Constants;
import aeolus.wind.spider.biz.dao.BDBStore;
import aeolus.wind.spider.biz.dataobject.Ability;
import aeolus.wind.spider.biz.dataobject.AbilityPackage;
import aeolus.wind.spider.biz.service.interfaces.AbilityService;

import com.sleepycat.je.SequenceConfig;
import com.sleepycat.je.Transaction;
import com.sleepycat.persist.EntityCursor;
import com.sleepycat.persist.EntityIndex;
import com.sleepycat.persist.EntityJoin;
import com.sleepycat.persist.EntityStore;
import com.sleepycat.persist.ForwardCursor;
import com.sleepycat.persist.PrimaryIndex;
import com.sleepycat.persist.SecondaryIndex;

public class AbilityServiceImpl implements AbilityService {

    private static EntityStore                                    abilityStore;
    private static PrimaryIndex<String, Ability>                  abilityIdIndex;
    private static SecondaryIndex<String, String, Ability>        abilityOwnerNameIndex;

    private static EntityStore                                    abilityPackageStore;
    private static PrimaryIndex<String, AbilityPackage>           abilityPackageIdIndex;
    private static SecondaryIndex<String, String, AbilityPackage> abilityPackageNameIndex;
    private static SecondaryIndex<String, String, AbilityPackage> abilityPackageOwnerNameIndex;

    static {
        BDBStore bdbStore = new BDBStore(Constants.ABILITY_BIZ_NAME);
        abilityStore = bdbStore.createEntityStore(Constants.ABILITY_BIZ_NAME);
        abilityIdIndex = abilityStore.getPrimaryIndex(String.class, Ability.class);
        abilityOwnerNameIndex = abilityStore.getSecondaryIndex(abilityIdIndex, String.class, "ownIdentityName");

        abilityPackageStore = bdbStore.createEntityStore(Constants.ABILITY_PACKAGE_BIZ_NAME);
        abilityPackageIdIndex = abilityPackageStore.getPrimaryIndex(String.class, AbilityPackage.class);
        abilityPackageNameIndex = abilityPackageStore.getSecondaryIndex(abilityPackageIdIndex, String.class,
                                                                        "ownIdentityName");
        abilityPackageOwnerNameIndex = abilityPackageStore.getSecondaryIndex(abilityPackageIdIndex, String.class,
                                                                             "ownIdentityName");

        // 创建自增ID
        SequenceConfig abSC = new SequenceConfig();
        abSC.setAllowCreate(true);
        abilityStore.setSequenceConfig("ability_seq", abSC);
        SequenceConfig abPackageSC = new SequenceConfig();
        abPackageSC.setAllowCreate(true);
        abilityPackageStore.setSequenceConfig("abilityPackage_seq", abPackageSC);
    }

    // // ability

    @Override
    public List<Ability> listAbilities(String identityName) {
        // TODO Auto-generated method stub

        List<Ability> list = new ArrayList<Ability>();
        Ability ability = null;
        EntityIndex<String, Ability> index = getAbilityOwnerSi().subIndex(identityName);
        EntityCursor<Ability> ec = index.entities();
        while ((ability = ec.next()) != null)
            list.add(ability);
        ec.close();
        return list;
    }

    @Override
    public Ability findAbility(String abilityId) {
        return abilityIdIndex.get(abilityId);
    }

    @Override
    public void saveAbility(Ability ability) {
        Transaction txn = getAbilityStore().getEnvironment().beginTransaction(null, null);
        ability.setId();
        getAbilityPi().put(txn, ability);
        txn.commit();
    }

    @Override
    public void deleteAbility(String id) {
        Transaction txn = getAbilityStore().getEnvironment().beginTransaction(null, null);
        getAbilityPi().delete(txn, id);
        txn.commit();
    }

    @Override
    public List<AbilityPackage> listAbilityPackages(String identityName) {
        List<AbilityPackage> list = new ArrayList<AbilityPackage>();
        AbilityPackage abilityPackage = null;
        EntityIndex<String, AbilityPackage> index = getAbilityPackageOwnerSi().subIndex(identityName);
        EntityCursor<AbilityPackage> ec = index.entities();
        while ((abilityPackage = ec.next()) != null)
            list.add(abilityPackage);
        ec.close();
        return list;
    }

    @Override
    public AbilityPackage findAbilityPackage(String abilityPackageId) {
        return abilityPackageIdIndex.get(abilityPackageId);
    }

    @Override
    public AbilityPackage findAbilityPackageByName(String identityName, String abilityPackageName) {
        EntityJoin<String, AbilityPackage> join = new EntityJoin<String, AbilityPackage>(getAbilityPackagePi());
        join.addCondition(getAbilityPackageOwnerSi(), identityName);
        join.addCondition(getAbilityPackageNameSi(), abilityPackageName);
        ForwardCursor<AbilityPackage> ec = join.entities();
        return ec.next();
    }

    @Override
    public void saveAbilityPackage(AbilityPackage abilityPackage) {
        Transaction txn = getAbilityPackageStore().getEnvironment().beginTransaction(null, null);
        abilityPackage.setId();
        getAbilityPackagePi().put(txn, abilityPackage);
        txn.commit();
    }

    @Override
    public void deleteAbilityPackage(String id) {
        Transaction txn = getAbilityPackageStore().getEnvironment().beginTransaction(null, null);
        getAbilityPackagePi().delete(txn, id);
        txn.commit();
    }

    //
    // @Override
    // public Set<String> getAbilitiyNames(String groupName, AbilityType abilityType) {
    // Set<String> set = new HashSet<String>();
    // AbilityPackage ability = null;
    // EntityIndex<String, AbilityPackage> index = getSi(groupName).subIndex(abilityType);
    // EntityCursor<AbilityPackage> ec = index.entities();
    // while ((ability = ec.next()) != null)
    // set.add(ability.getName());
    // ec.close();
    // return set;
    // }
    //
    // @Override
    // public Map<AbilityType, List<AbilityPackage>> listAbilitiesByType(String groupName) {
    // Map<AbilityType, List<AbilityPackage>> abilityMap = new HashMap<AbilityType, List<AbilityPackage>>();
    // AbilityType[] abilityTypes = AbilityType.values();
    // for (AbilityType abType : abilityTypes) {
    // abilityMap.put(abType, listAbilities(groupName, abType));
    // }
    // return abilityMap;
    // }
    //

    private EntityStore getAbilityStore() {
        return abilityStore;
    }

    private PrimaryIndex<String, Ability> getAbilityPi() {
        return abilityIdIndex;
    }

    private SecondaryIndex<String, String, Ability> getAbilityOwnerSi() {
        return abilityOwnerNameIndex;
    }

    private EntityStore getAbilityPackageStore() {
        return abilityPackageStore;
    }

    private PrimaryIndex<String, AbilityPackage> getAbilityPackagePi() {
        return abilityPackageIdIndex;
    }

    private SecondaryIndex<String, String, AbilityPackage> getAbilityPackageNameSi() {
        return abilityPackageNameIndex;
    }

    private SecondaryIndex<String, String, AbilityPackage> getAbilityPackageOwnerSi() {
        return abilityPackageOwnerNameIndex;
    }

    public static void main(String args[]) {
        String ownerName = "袁岳峰";
        AbilityService as = new AbilityServiceImpl();
        Ability ab1 = new Ability("硬testname", "硬testdesc", "袁岳峰");
        Ability ab2 = new Ability("硬testname2", "硬testdesc2", "袁岳峰");
        as.saveAbility(ab1);
        as.saveAbility(ab2);
        AbilityPackage abilityPackage = new AbilityPackage();
        abilityPackage.setPackageName("硬实力");
        abilityPackage.addAbility(ab1.getId());
        abilityPackage.addAbility(ab2.getId());
        abilityPackage.setOwnIdentityName(ownerName);
        as.saveAbilityPackage(abilityPackage);
        Ability abS1 = new Ability("软testname", "软testdesc", "袁岳峰");
        Ability abS2 = new Ability("软testname2", "软testdesc2", "袁岳峰");
        as.saveAbility(abS1);
        as.saveAbility(abS2);
        AbilityPackage abilityPackage2 = new AbilityPackage();
        abilityPackage2.setPackageName("软实力");
        abilityPackage2.addAbility(abS1.getId());
        abilityPackage2.addAbility(abS2.getId());
        abilityPackage2.setOwnIdentityName(ownerName);
        as.saveAbilityPackage(abilityPackage2);
        // as.deleteAbility("责任感");
        List<Ability> list = as.listAbilities("袁岳峰");
        for (Ability ab : list) {
            System.out.println("能力名: " + ab.getName());
            System.out.println("能力描述: " + ab.getDescription());
        }

        List<AbilityPackage> listPackage = as.listAbilityPackages("袁岳峰");
        for (AbilityPackage a : listPackage) {
            System.out.println("能力包名: " + a.getPackageName());
            for (String ab : a.getAbilityIdSet()) {
                System.out.println("能力名: " + ab);
            }
        }
    }
}
